import React, {
  Component,
  createRef,
  createContext,
  useRef,
  useState,
  useEffect,
} from "react";
import PropType, { func } from 'prop-types'
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import * as THREE from 'three';
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"

import { FirstPersonControls } from 'three/examples/jsm/controls/FirstPersonControls'; //第一人称控制器
import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls';
import gsap from 'gsap'; //动画库
import Stats from 'stats.js'; //性能监控
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'; // FBX 模型加载器
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; //模型加载器
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; //模型解压缩
const width =  window.innerWidth ;
const height = window.innerHeight

const myHeight =1.8;
const clock = new THREE.Clock(); 
const  stats = new Stats(); 

const scene = new THREE.Scene();
scene.background = new THREE.Color( 0xffffff );
scene.fog = new THREE.Fog( 0xffffff, 0, 750 );



const camera = new THREE.PerspectiveCamera( 45,width / height, 1, 12000 );
camera.position.y = myHeight;


const renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(width, height );

const loader = new GLTFLoader(); //gltf模型加载器
 
const dracoLoader = new DRACOLoader(); //模型解压缩


const controls = new PointerLockControls( camera, renderer.domElement ); //指针锁定控制器（PointerLockControls）



let prevTime = performance.now(); //返回当前时间戳，精度为微秒。
		

			let moveForward = false;
			let moveBackward = false;
			let moveLeft = false;
			let moveRight = false;
			let canJump = false;

		
			const velocity = new THREE.Vector3();
			const direction = new THREE.Vector3();
      let mixer:any;		
const ReactDemo=()=>{

 useEffect(()=>{
  animate();
  init()
 },[])

 
    const init =()=>{
    const container = document.createElement( 'div' );
    document.body.appendChild( container );

    
 

    const hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 );
    hemiLight.position.set( 0, 1, 0 );
    scene.add( hemiLight );

    const dirLight = new THREE.DirectionalLight( 0xffffff );
    dirLight.position.set( 0, 1, 0 );
    scene.add( dirLight );

   

    // stats
    
    container.appendChild( stats.dom );

    // model   

    dracoLoader.setDecoderPath('./draco');
    loader.setDRACOLoader(dracoLoader);
    loader.load( '3D/111111.glb' , function ( object ) {

      const model = object.scene;
      scene.add( model );
      mixer = new THREE.AnimationMixer( model );
      for(let i =0 ;i< object.animations.length;i++){
      
        mixer.clipAction( object.animations[i] ).play(); 
      }
            // mixer.clipAction( object.animations[0] ).play(); //说明: 不要直接调用这个构造函数，而应该先用AnimationMixer.clipAction实例化一个AnimationAction，因为这个方法提供了缓存以提高性能。
      console.log( object,model,'-------------------->',mixer)
      animate();

    } );


    container.appendChild( renderer.domElement );

 
    window.addEventListener('keydown',hanldeKeydown); 
    window.addEventListener('keyup',hanldeKeyKeyup); 

    window.addEventListener( 'resize', onWindowResize );

    window.addEventListener('click',clickModle)

    controls.addEventListener('lock',controlsLock) //指针锁定控制器（PointerLockControls） 特有事件

    scene.add( controls.getObject() );

   
  }
  function hanldeKeydown(event:any){
    switch ( event.code ) {

      case 'ArrowUp':
      case 'KeyW':
        moveForward = true;
        break;

      case 'ArrowLeft':
      case 'KeyA':
        moveLeft = true;
        break;

      case 'ArrowDown':
      case 'KeyS':
        moveBackward = true;
        break;

      case 'ArrowRight':
      case 'KeyD':
        moveRight = true;
        break;

      case 'Space': // 空格键
        if ( canJump === true ) velocity.y += 150;  // 弹跳
        canJump = false;
        break;

    }
  }
  function hanldeKeyKeyup(event:any){
    switch ( event.code ) {

      case 'ArrowUp':
      case 'KeyW':
        moveForward = false;
        break;

      case 'ArrowLeft':
      case 'KeyA':
        moveLeft = false;
        break;

      case 'ArrowDown':
      case 'KeyS':
        moveBackward = false;
        break;

      case 'ArrowRight':
      case 'KeyD':
        moveRight = false;
        break;

    }
  }
  function clickModle(){
    controls.lock(); //当指针状态为 “locked” （即鼠标被捕获）时触发。
    console.log(' wo dian za111i ')
  }
  function controlsLock(){
    console.log(' wo dian zai ')

  }
  function onWindowResize() {

    camera.aspect = width / height;
    camera.updateProjectionMatrix();
  
    renderer.setSize( width, height );

  }

  //

  function animate() {

    requestAnimationFrame( animate );
    const time = performance.now();

    if ( controls.isLocked === true ) {

     
      const deltaAnimation = clock.getDelta();	
      if(mixer){
        // console.log('1223',mixer)
        mixer.update( deltaAnimation );
      }
     

      const delta = ( time - prevTime ) / 3000;
     

      velocity.x -= velocity.x * 10.0 * delta;
      velocity.z -= velocity.z * 10.0 * delta;

      velocity.y -= 9.8 * 100.0 * delta; // 100.0 = mass
      // 前后运动是Z轴
      // 左右运动是X轴
      direction.z = Number( moveForward ) - Number( moveBackward );
      direction.x = Number( moveRight ) - Number( moveLeft );
      direction.normalize(); //这确保了所有方向的一致运动 this ensures consistent movements in all directions

      if ( moveForward || moveBackward ) velocity.z -= direction.z * 400.0 * delta;
      if ( moveLeft || moveRight ) velocity.x -= direction.x * 400.0 * delta;

    

      controls.moveRight( - velocity.x * delta ); // 距离（区分正负）。平行于xz平面，向前移动摄像机。假定camera.up是y朝上。
      controls.moveForward( - velocity.z * delta );// 距离（区分正负）。 平行于xz平面，向侧面移动摄像机。

      controls.getObject().position.y += ( velocity.y * delta ); // new behavior 新行为 (修改相机的位置)

      if ( controls.getObject().position.y < myHeight ) {

        velocity.y = 0;
        controls.getObject().position.y = myHeight;

        canJump = true;

      }

    }
    prevTime = time;
    renderer.render( scene, camera );


   
    stats.update();

  }
  return (<>
   
    
    <div id="id"></div>
  </>)
}

export default ReactDemo;
